package cn.neu.leon.local;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import cn.neu.leon.util.AdverbDict;
import cn.neu.leon.util.EmotionLexicon;
import cn.neu.leon.util.NlpirInit;
import cn.neu.leon.util.Percentage;

public class Sax4Xml{
	
    static int day = 2;
	
	public static void main(String[] args) throws Exception {

	  
		   String xmlFile = "E:/library/weibo/1031去重后.xml";  //微博语料库xml文件
			// step 1: 获得SAX解析器工厂实例
	       SAXParserFactory factory = SAXParserFactory.newInstance();

	       // step 2: 获得SAX解析器实例
	       SAXParser parser = factory.newSAXParser();

	       // step 3: 开始进行解析
	       // 传入待解析的文档的处理器
	       
	       parser.parse(new File(xmlFile), new MyHandler());
}
}

class MyHandler extends DefaultHandler
{
   private String csvFile ="E:/library/weibo/2011-10.csv";         //情感分析后的情感值存入的csv文件
   private String sInput=null;
   private String resultString=null;
   private static int i =0;   
   private static int n =0;
   private boolean hasSen = false;
   private String strEmotion = null; // 定义情感字符串
   EmotionLexicon el = new EmotionLexicon();
   HashMap<String, double[]> em = el.getEmotionMap();// 获取情感词典的hashmap
	
   // Iterator it = em.keySet().iterator();
	private double prob[] = new double[7];        //7中情感值
	private double daySentiment[] = new double[7]; //一天的情感值数组
	Element theElem = null;
    NlpirInit nlpirinit = new NlpirInit();
	private StringBuilder sb = new StringBuilder();

   @Override
   public void startDocument() throws SAXException
   {
       System.out.println("start document -> parse begin");
       
   }

   @Override
   public void endDocument() throws SAXException
   {
	double[] d = new double[7];
   	System.out.println("end document -> parse finished");
   	System.out.println(i+" "+n);
   	for (int k = 0; k < 7; k++) {
   		d[k] = daySentiment[k]/n;
   		System.out.println(d[k]);
   	}
   	
   	try {
   		File csv = new File(csvFile);
		BufferedWriter bw = new BufferedWriter(new FileWriter(csv,true));
		bw.write(d[0]+","+d[1]+","+d[2]+","+d[3]+","+d[4]+","+d[5]+","+d[6]+","+n+","+i);
		bw.newLine();
		bw.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
   
   }

   @Override
   public void startElement(String uri, String localName, String qName,
           Attributes attributes) throws SAXException
   {
   	
   	
   		//System.out.println(qName);
   		sb.setLength(0);  
   		
   }

   @Override
   public void characters(char[] ch, int start, int length)
           throws SAXException
   {
   	sb.append(ch,start,length);
   	
   }

   @Override
   public void endElement(String uri, String localName, String qName)
           throws SAXException
   {
//   	if(currentTag == "text")
//   	{
//   	sInput = sb.toString();
//   	System.out.println("第"+i+"条: "+sInput);
//   	i++;
//   	}
   	/*当解析到</text>时，sb就是一条完整的微博，对其分词，情感分析，最后累加进prob数组*/
	   if(qName=="text")
       {
       	sInput = sb.toString();
       	sInput =sInput.replaceAll("\r|\n|\t", ""); //去除微博中的\r \n \t，这些会导致分词异常
       	System.out.println("第"+i+"条: ");
       	System.out.println(sInput);
       	i++;
//       	try {
//       		if(i==378340)
//				Thread.sleep(2341324);
//			} catch (InterruptedException e1) {
//				// TODO Auto-generated catch block
//				e1.printStackTrace();
//			}
       	try {
				if(sInput != null) 
				{
					resultString = nlpirinit.instance.NLPIR_ParagraphProcess(sInput, 1); // nlpir进行分词
					//nlpirinit.initTest();
//					System.out.println("分词结果为：\n " + resultString);
				}
					String[] strArray = resultString.split(" "); // 将分词结果放入数组中
				
				
				for (int j = 0; j < strArray.length; j++) { //遍历每一个分词
					// System.out.println(strArray[j]);
					
					// 若存在匹配的表情符号，则该条微博情感值由该表情决定
					if(strArray[j].endsWith("/xm"))
					{
						
						hasSen = true;    
						strEmotion = strArray[j].split("/")[0]; //取出带词性标志分词的中文词
						if(em.containsKey(strEmotion))
						{
							prob = em.get(strEmotion);
							for(int k = 0;k<7;k++)
							{
								daySentiment[k] += prob[k];
							}
							break;
						}
								
					}	
					
					/*将以下有意义词性的分词取出进行分析*/
					if (strArray[j].endsWith("/v") // 动词 5645
							|| strArray[j].endsWith("/vi")
							|| strArray[j].endsWith("/n")
							|| strArray[j].endsWith("/a")
							|| strArray[j].endsWith("/vl")
							|| strArray[j].endsWith("/vn")
							|| strArray[j].endsWith("/ng")
							|| strArray[j].endsWith("/al")
							|| strArray[j].endsWith("/an")
							|| strArray[j].endsWith("/ng")
							|| strArray[j].endsWith("/nl")
							|| strArray[j].endsWith("/z")) {
						strEmotion = strArray[j].split("/")[0]; //取出带词性标志分词的中文词
						// System.out.println(strEmotion);
						/*如果分词在HashMap中存在，则取出value，放入临时数组中*/
						if (em.get(strEmotion) != null) { 
							hasSen = true;
							prob = em.get(strEmotion);
							
							int aDegree;
							int aNegative;
							int negNum = 0;
							double degree = 1.0;
							int negative = 0;
							//查情感词所在分句前有没有程度副词，及其位置
							for(int k=j-1;k>=0&&!strArray[k].endsWith("/wd") //逗号
							&&!strArray[k].endsWith("/wf")//分号
							&&!strArray[k].endsWith("/ww")//问号
							&&!strArray[k].endsWith("/wt");k--)//感叹号
							{
								degree = AdverbDict.degree(strArray[k].split("/")[0]);						
								if(degree != 1.0 ) 
								{
									aDegree = k;
									break;
								}
							}
							//查找情感词所在分句前有没有否定副词，及其位置和个数
							for(int k=j-1;k>=0&&!strArray[k].endsWith("/wd") //逗号
							&&!strArray[k].endsWith("/wf")//分号
							&&!strArray[k].endsWith("/ww")//问号
							&&!strArray[k].endsWith("/wt");k--){//感叹号
								negative = AdverbDict.negative(strArray[k].split("/")[0]);
								if(negative == -1)
									{
										aNegative = k;
										negNum++;
									}
							}
							/*不存在否定副词时,情感值乘上程度副词强度，再累加*/
							if(negNum == 0)
							for (int m = 0; m < 7; m++) {
								daySentiment[m] += degree*prob[m];
							}
							/*存在否定副词时，且个数是奇数,厌恶和喜好，悲伤和高兴交换情感值，再累加*/
							else if(negNum%2 == 1)
							{
								double temp;
								temp = prob[0];
								prob[0] = prob[4];
								prob[4] = temp;
								temp = prob[1];
								prob[1] = prob[3];
								prob[3] = temp;
								
								for (int m = 0; m < 7; m++) {
									daySentiment[m] += degree*prob[m];
								}
							}
							else
								for (int m = 0; m < 7; m++) {
									daySentiment[m] += degree*prob[m];
								}
								
						}
					}

				}
				
			if(hasSen == true)
			{
				n++;
				hasSen = false;
			}

			} catch (Exception e) {
				System.out.println("错误信息：");
				e.printStackTrace();
			}
       	
       }

   }
}



